﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.Common;
using System.Data.OleDb;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lacrima.Framework.Persistence
{
    /// <summary>
    /// 数据库访问抽象类DbManager.
    /// </summary>
    public abstract class DbManager : IDbManager, IDisposable
    {
        /// <summary>
        /// 数据库连接字符串
        /// </summary>
        /// <value>The connection string.</value>
        protected string connectionString { get; set; }
        protected IDbAdapter dbAdapter { get; set; }
        protected IDbConnection dbConnection { get; set; }
        protected IDbCommand dbCommand { get; set; }
        protected IDbTransaction dbTransaction { get; set; }

        public DbManager(string strConnectionString)
        {
            this.connectionString = strConnectionString;
        }

        public DbManager(Enum entity)
        {
            this.connectionString = ConfigurationManager.AppSettings[entity.ToString()];
        }

        /// <summary>
        /// 打开数据库连接
        /// </summary>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public virtual bool Open()
        {
            try
            {
                if (this.dbConnection == null)
                {
                    this.dbConnection = this.dbAdapter.GetInstance().GetDbConnection(this.connectionString);
                    this.dbConnection.Open();
                    this.dbCommand = this.dbAdapter.GetInstance().GetDbCommand(this.dbConnection);
                }
                else if (!this.dbConnection.State.Equals(ConnectionState.Open))
                {
                    this.dbConnection.Open();
                    this.dbCommand = this.dbAdapter.GetInstance().GetDbCommand(this.dbConnection);
                }
                return true;
            }
            catch(Exception ex)
            {
                throw ex;
            }
        }

        public virtual bool OpenForTransaction()
        {
            try
            {
                if (true == this.Open())
                {
                    this.dbTransaction = this.dbAdapter.GetInstance().GetDbTransaction(this.dbConnection);
                    this.dbCommand.Transaction = dbTransaction;
                }
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public virtual int ExecuteNonQuery(string strNonQuerySql)
        {
            try
            {
                this.dbCommand.CommandText = strNonQuerySql;
                int affectedRows = this.dbCommand.ExecuteNonQuery();
                return affectedRows;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public virtual IDataReader ExecuteQuery(string strQuerySql)
        {
            try
            {
                this.dbCommand.CommandText = strQuerySql;
                IDataReader reader = this.dbCommand.ExecuteReader();
                return reader;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public virtual bool ExecuteQuery(string strQuerySql, out System.Data.DataTable table)
        {
            try
            {
                table = new DataTable();
                this.dbCommand.CommandText = strQuerySql;
                DbDataAdapter dataAdapter = this.dbAdapter.GetDbDataAdapter(this.dbCommand);
                dataAdapter.Fill(table);
                return true;
            }
            catch (Exception ex)
            {
                table = null;
                throw ex;
            }
        }

        public virtual bool Rollback()
        {
            try
            {
                if (null != this.dbTransaction)
                {
                    this.dbTransaction.Rollback();
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public virtual bool Commit()
        {
            try
            {
                if (null != this.dbTransaction)
                {
                    this.dbTransaction.Commit();
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public virtual bool Close()
        {
            Dispose();
            return true;
        }

        public virtual void Dispose()
        {
            try
            {
                if (null != this.dbTransaction)
                {
                    this.dbTransaction.Dispose();
                }

                if (null != this.dbCommand)
                {
                    this.dbCommand.Dispose();
                }

                if (null != this.dbConnection)
                {
                    this.dbConnection.Close();
                    this.dbConnection.Dispose();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                this.dbTransaction = null;
                this.dbCommand = null;
                this.dbConnection = null;
            }
        }
    }
}
